<?php

namespace App\Http\Controllers\WebApp\Api;

use App\Events\CreateOrder;
use App\Events\OrderStop;
use App\Exceptions\ApiException;
use App\Http\Requests\ChargeOrderPost;
use App\Http\Requests\OrderPost;
use App\Tables\Device;
use Illuminate\Http\Request;

use ChargeOrder;
use Order;
use App\Tables\Order as OrderTable;
use XmtApp\Payment\Alipay\HandleNotify;

class OrderController extends BaseController
{
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 订单列表
     * @param Request $request
     * @return UsersResource
     */
    public function index(Request $request)
    {
        $query = new OrderTable();
        $query = $query->where('user_id', $this->user->id);
        /**
         * 设置查询条件
         */

        if ($request->filled('keyword')) {
            $query = $query->where(function($query) use ($request) {
                $query->orWhere('order_sn', 'like', "%{$request->keyword}%");
                $query->orWhere('device_sn', 'like', "%{$request->keyword}%");
            });
        }

        /**
         * 排序
         */
        $query = $query->orderBy('created_at', 'desc');

        /**
         * 分页
         */
        $page = $request->get('page', 1);
        $pageSize = $request->header('pageSize') ?: $request->get('pageSize', 20);

        $skip = $pageSize * ($page - 1);
        $data = $query->skip($skip)->take($pageSize)->get();

        $data = array_map(function ($item) {
            return collect($item)->except(['agent', 'device']);
        }, $data->toArray());

        return response()->json(ajax_return(true, 'ok', $data));
    }

    /**
     * 生成订单
     * @param OrderPost $post
     * @return \Illuminate\Http\JsonResponse
     * @throws ApiException
     */
    public function create(OrderPost $post)
    {
        $device = Device::where('device_sn', $post->device_sn)->first();
        if (empty($device)) {
            throw new ApiException('设备信息不存在');
        }

        if ($device->status == 'fault') {
            throw new ApiException('设备发生故障，暂无法使用');
        }

        if ($device->status == 'offline') {
            throw new ApiException('设备离线，暂无法使用');
        }

        if ($device->ports[$post->port] == 1) {
            throw new ApiException('充电端口正在使用中');
        }


        $order = Order::create($this->user->id, $post->device_sn, $post->port, $post->get('source', 'web'));
        if ($order === false) {
            throw new ApiException('下单失败, 请确保您的账户余额充足');
        }

        // 发送设备开启消息
        event(new CreateOrder($order));

        return response()->json(ajax_return(true, '下单成功', ['order_sn' => $order->order_sn]));
    }

    /**
     * 发送订单设备停止指令
     * @param $order_sn
     * @return \Illuminate\Http\JsonResponse
     * @throws ApiException
     */
    public function stop ($order_sn)
    {
        $order = OrderTable::where('order_sn', $order_sn)->first();

        if (empty($order)) {
            throw new ApiException('订单信息不存在');
        }

        if ($order->user_id != $this->user->id) {
            throw new ApiException('这个不是你的订单，操作失败');
        }

        if ($order->status !== 'service') {
            throw new ApiException('订单状态不在服务中，操作失败');
        }

        // 发送设备停止指令到消息队列
        event(new OrderStop($order));

        return response()->json(ajax_return(true, '停止指令已发送成功'));
    }

    /**
     * 获取订单详情
     * @param $order_sn
     * @return \Illuminate\Http\JsonResponse
     * @throws ApiException
     */
    public function detail($order_sn)
    {
        $order = OrderTable::where('order_sn', $order_sn)->where('user_id', $this->user->id)->first();

        if (empty($order)) {
            throw new ApiException('订单信息获取失败');
        }

        $order = collect($order->toArray())->except(['agent', 'device', 'user']);

        return response()->json(ajax_return(true, '获取订单信息成功', $order));
    }

    /**
     * 用户充值
     * @param ChargeOrderPost|Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws ApiException
     */
    public function charge(ChargeOrderPost $request)
    {
        $money = $request->money;
        $pay_mode = $request->pay_mode;
        $pay_source = strtolower($request->get('source', 'wap'));

        /**
         * 生成充值订单
         */
        $order = ChargeOrder::create($this->user->id, $money, $pay_mode, $pay_source);
        if (empty($order)) {
            throw new ApiException('生成充值订单失败');
        }

        /**
         * 生成支付参数
         */
        if ($pay_mode == 'wxpay') {
            $wx_notify_url = route('order.charge.wxpay.app.notify');

            $openid = '';
            if ($pay_source == 'wap') {
                $openid = $request->get('openid');
                if (empty($openid)) {
                    throw new ApiException('获取微信openID失败，支付失败', $openid);
                }
                $wx_notify_url = route('order.charge.wxpay.notify');
            }
            $resp = ChargeOrder::wxpay($order->order_sn, $openid, $wx_notify_url, $pay_source);
            if ($resp === false) {
                throw new ApiException('生成微信支付单失败');
            }
            return response()->json(ajax_return(true, '生成充值订单成功', ['order_sn' => $order->order_sn, 'pay_config' => $resp]));
        } else if ($pay_mode == 'alipay') {
            $resp = ChargeOrder::alipay($order->order_sn, $pay_source);
            if ($resp === false) {
                throw new ApiException('生成支付宝支付失败');
            }

            return response()->json(ajax_return(true, '生成充值订单成功', ['order_sn' => $order->order_sn, 'pay_config' => $resp]));
        }

        return response()->json(ajax_return(false, '支付失败'));
    }

    /**
     * 获取充值订单列表
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function chargeList(Request $request)
    {
        $query = new \App\Tables\ChargeOrder();
        $query = $query->where('user_id', $this->user->id);

        /**
         * 设置查询条件
         */
        if ($request->filled('keyword')) {
            $query = $query->where(function($query) use ($request) {
                $query->orWhere('order_sn', 'like', "%{$request->keyword}%");
            });
        }

        /**
         * 排序
         */
        $query = $query->orderBy('created_at', 'desc');

        /**
         * 分页
         */
        $page = $request->get('page', 1);
        $pageSize = $request->header('pageSize') ?: $request->get('pageSize', 20);

        $skip = $pageSize * ($page - 1);
        $data = $query->skip($skip)->take($pageSize)->get();

        $data = array_map(function ($item) {
            return collect($item)->except(['user']);
        }, $data->toArray());

        return response()->json(ajax_return(true, 'ok', $data));
    }

    /**
     * 处理充值订单微信回调
     */
    public function chargeOrderWxpayNotify()
    {
        ChargeOrder::handleNotify();
    }

    /**
     * 处理App充值订单微信回调
     */
    public function chargeOrderAppWxpayNotify()
    {
        ChargeOrder::handleAppNotify();
    }

    /**
     * 处理充值订单支付宝异步回调
     * @param HandleNotify $notify
     */
    public function chargeOrderAlipayNotify(HandleNotify $notify)
    {
         return ChargeOrder::handleAlipayNotify($notify);
    }

    /**
     * 处理充值订单支付宝同步回调
     * @param HandleNotify $notify
     */
    public function chargeOrderAlipayReturn(HandleNotify $notify)
    {
        return ChargeOrder::handleAlipayReturn($notify);
    }
}
